package main

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
	"math/big"
    //"os/exec"
	"crypto"
	//"crypto/rand"
	"crypto/sha256"
)

var privateKey = []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAPvaxeMpiYNmKwTWuYPRME5KGzd2eEE0U1Y4sT7IWZsO1UU8a6GU
u8MGPPn700pH3Hf31pro3c6/NZBmggY859MCAwEAAQJAJ6+elSAbeigkSTvoubvB
5+RHi6LQaj3rj9+ZFnKNpCAPNpPJm8YTg9Xm/xi9A/vraW8lLSfzUlwkSByp1+nX
OQIhAP/RG176U+PDC272B+nfjHxFt7fKHEM5PCktMSqjPltdAiEA/AjwlOHDmcGG
X4d3kMCN7VBBsRcfou4sC+kF2JMeTO8CIFV1AETBMScD8BzYOZqKID8fdxkBfmGC
jDNhMmyA7gLNAiEAp8afuMxtdG5SsEcyveag1Ein4mZ9Re383lTZ8mlFM3sCICtK
Dy8saGF8uhdy/gREN0+K4vOxrf7y1t+mZDHTRCxg
-----END RSA PRIVATE KEY-----
`)

var (
    ErrInputSize  = errors.New("input size too large")
    ErrEncryption = errors.New("encryption error")
)

func PrivateEncrypt(priv *rsa.PrivateKey, data []byte) (enc []byte, err error) {

    k := (priv.N.BitLen() + 7) / 8
    tLen := len(data)
    // rfc2313, section 8:
    // The length of the data D shall not be more than k-11 octets
    if tLen > k-11 {
        err = ErrInputSize
        return
    }
    em := make([]byte, k)
    em[1] = 1
    for i := 2; i < k-tLen-1; i++ {
        em[i] = 0xff
    }
    copy(em[k-tLen:k], data)
    c := new(big.Int).SetBytes(em)
    if c.Cmp(priv.N) > 0 {
        err = ErrEncryption
        return
    }
    var m *big.Int
    var ir *big.Int
    if priv.Precomputed.Dp == nil {
        m = new(big.Int).Exp(c, priv.D, priv.N)
    } else {
        // We have the precalculated values needed for the CRT.
        m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
        m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
        m.Sub(m, m2)
        if m.Sign() < 0 {
            m.Add(m, priv.Primes[0])
        }
        m.Mul(m, priv.Precomputed.Qinv)
        m.Mod(m, priv.Primes[0])
        m.Mul(m, priv.Primes[1])
        m.Add(m, m2)

        for i, values := range priv.Precomputed.CRTValues {
            prime := priv.Primes[2+i]
            m2.Exp(c, values.Exp, prime)
            m2.Sub(m2, m)
            m2.Mul(m2, values.Coeff)
            m2.Mod(m2, prime)
            if m2.Sign() < 0 {
                m2.Add(m2, prime)
            }
            m2.Mul(m2, values.R)
            m.Add(m, m2)
        }
    }

    if ir != nil {
        // Unblind.
        m.Mul(m, ir)
        m.Mod(m, priv.N)
    }
    enc = m.Bytes()
    return
}

// SHA256 sha256
func sHA256(data []byte) []byte {
	h := sha256.New()
	h.Write(data)
	return h.Sum(nil)
}

func main() {
    block, _ := pem.Decode(privateKey)
    privkey, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
	
	originMsg := "aPdD4PDWJxyQWWrFalBDsjdYjdzRMt2wqkS4mJkfKMc="
	hashValue := sHA256([]byte(originMsg))
    encData, _ := PrivateEncrypt(privkey, []byte(hashValue))
    fmt.Println(encData)
    fmt.Println(base64.StdEncoding.EncodeToString(encData))

   
}